#!/usr/bin/env python3
"""
Web监控面板
提供可视化的交易监控界面
"""

import asyncio
import sys
from pathlib import Path
from flask import Flask, render_template, jsonify, request
from flask_cors import CORS
import json
from datetime import datetime, timedelta
import requests
import pandas as pd

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from xcquant.core import unified_core, unified_logger


class WebDashboard:
    """Web监控面板"""
    
    def __init__(self, config_path: str):
        self.config_path = config_path
        self.logger = unified_logger.get_logger(__name__)
        self.app = Flask(__name__)
        CORS(self.app)
        
        # 模拟数据存储
        self.trading_data = {
            'strategies': [],
            'orders': [],
            'positions': [],
            'pnl_history': [],
            'system_status': {
                'status': 'running',
                'uptime': datetime.now(),
                'total_trades': 0,
                'total_pnl': 0.0
            }
        }
        
        self._setup_routes()
        
    def _setup_routes(self):
        """设置路由"""
        
        @self.app.route('/')
        def index():
            """主页"""
            return self._render_dashboard()
            
        @self.app.route('/api/status')
        def api_status():
            """系统状态API"""
            return jsonify(self.trading_data['system_status'])
            
        @self.app.route('/api/strategies')
        def api_strategies():
            """策略状态API"""
            return jsonify(self.trading_data['strategies'])
            
        @self.app.route('/api/orders')
        def api_orders():
            """订单API"""
            return jsonify(self.trading_data['orders'])
            
        @self.app.route('/api/positions')
        def api_positions():
            """持仓API"""
            return jsonify(self.trading_data['positions'])
            
        @self.app.route('/api/pnl')
        def api_pnl():
            """盈亏历史API"""
            return jsonify(self.trading_data['pnl_history'])
            
        @self.app.route('/api/trading_chart')
        def api_trading_chart():
            """交易图表数据API"""
            return jsonify(self._get_trading_chart_data())
            
        @self.app.route('/api/price_data')
        def api_price_data():
            """价格数据API"""
            symbol = request.args.get('symbol', 'BTC-USDT')
            timeframe = request.args.get('timeframe', '1H')
            return jsonify(self._get_price_data(symbol, timeframe))
                
    def _render_dashboard(self):
        """渲染监控面板"""
        html_template = '''
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XCQuant 模拟交易监控</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            color: #333;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .header {
            text-align: center;
            color: white;
            margin-bottom: 30px;
        }
        
        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        .header p {
            font-size: 1.2em;
            opacity: 0.9;
        }
        
        .dashboard {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
        }
        
        .card {
            background: white;
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            transition: transform 0.3s ease;
        }
        
        .card:hover {
            transform: translateY(-5px);
        }
        
        .card h3 {
            color: #4a5568;
            margin-bottom: 15px;
            font-size: 1.3em;
            border-bottom: 2px solid #e2e8f0;
            padding-bottom: 10px;
        }
        
        .status-card {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
        }
        
        .status-card h3 {
            color: white;
            border-bottom-color: rgba(255,255,255,0.3);
        }
        
        .metric {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 10px 0;
            padding: 10px;
            background: #f7fafc;
            border-radius: 8px;
        }
        
        .metric-label {
            font-weight: 600;
            color: #4a5568;
        }
        
        .metric-value {
            font-weight: bold;
            color: #2d3748;
        }
        
        .positive {
            color: #38a169 !important;
        }
        
        .negative {
            color: #e53e3e !important;
        }
        
        .strategy-item {
            background: #f7fafc;
            border-radius: 8px;
            padding: 15px;
            margin: 10px 0;
            border-left: 4px solid #4facfe;
        }
        
        .strategy-name {
            font-weight: bold;
            color: #2d3748;
            margin-bottom: 5px;
        }
        
        .strategy-details {
            font-size: 0.9em;
            color: #718096;
        }
        
        .order-item {
            background: #f7fafc;
            border-radius: 8px;
            padding: 12px;
            margin: 8px 0;
            border-left: 4px solid #48bb78;
        }
        
        .order-header {
            display: flex;
            justify-content: space-between;
            font-weight: bold;
            margin-bottom: 5px;
        }
        
        .order-details {
            font-size: 0.9em;
            color: #718096;
        }
        
        .refresh-btn {
            position: fixed;
            bottom: 30px;
            right: 30px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 50px;
            padding: 15px 25px;
            font-size: 16px;
            cursor: pointer;
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            transition: all 0.3s ease;
        }
        
        .refresh-btn:hover {
            transform: scale(1.05);
            box-shadow: 0 8px 25px rgba(0,0,0,0.3);
        }
        
        .loading {
            text-align: center;
            padding: 20px;
            color: #718096;
        }
        
        .chart-container {
            width: 100%;
            height: 400px;
            margin: 20px 0;
        }
        
        .chart-controls {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
            flex-wrap: wrap;
        }
        
        .chart-controls select, .chart-controls button {
            padding: 8px 12px;
            border: 1px solid #e2e8f0;
            border-radius: 6px;
            background: white;
            cursor: pointer;
        }
        
        .chart-controls button {
            background: #4facfe;
            color: white;
            border: none;
        }
        
        .chart-controls button:hover {
            background: #3182ce;
        }
        
        @media (max-width: 768px) {
            .dashboard {
                grid-template-columns: 1fr;
            }
            
            .container {
                padding: 10px;
            }
            
            .header h1 {
                font-size: 2em;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🚀 XCQuant 模拟交易监控</h1>
            <p>实时监控您的量化交易策略</p>
        </div>
        
        <div class="dashboard">
            <!-- 系统状态 -->
            <div class="card status-card">
                <h3>📊 系统状态</h3>
                <div id="system-status">
                    <div class="loading">加载中...</div>
                </div>
            </div>
            
            <!-- 策略状态 -->
            <div class="card">
                <h3>🎯 交易策略</h3>
                <div id="strategies">
                    <div class="loading">加载中...</div>
                </div>
            </div>
            
            <!-- 活跃订单 -->
            <div class="card">
                <h3>📋 活跃订单</h3>
                <div id="orders">
                    <div class="loading">加载中...</div>
                </div>
            </div>
            
            <!-- 持仓信息 -->
            <div class="card">
                <h3>💼 持仓信息</h3>
                <div id="positions">
                    <div class="loading">加载中...</div>
                </div>
            </div>
            
            <!-- 盈亏统计 -->
            <div class="card">
                <h3>💰 盈亏统计</h3>
                <div id="pnl">
                    <div class="loading">加载中...</div>
                </div>
            </div>
            
            <!-- 快速操作 -->
            <div class="card">
                <h3>⚡ 快速操作</h3>
                <div style="display: flex; flex-direction: column; gap: 10px;">
                    <button onclick="refreshData()" style="padding: 10px; border: none; border-radius: 5px; background: #4facfe; color: white; cursor: pointer;">刷新数据</button>
                    <button onclick="exportData()" style="padding: 10px; border: none; border-radius: 5px; background: #48bb78; color: white; cursor: pointer;">导出数据</button>
                    <button onclick="showLogs()" style="padding: 10px; border: none; border-radius: 5px; background: #ed8936; color: white; cursor: pointer;">查看日志</button>
                </div>
            </div>
        </div>
        
        <!-- 交易图表区域 -->
        <div class="card" style="grid-column: 1 / -1; margin-top: 20px;">
            <h3>📈 历史交易图表</h3>
            <div class="chart-controls">
                <select id="chart-symbol">
                    <option value="BTC-USDT">BTC-USDT</option>
                    <option value="ETH-USDT">ETH-USDT</option>
                    <option value="SOL-USDT">SOL-USDT</option>
                </select>
                <select id="chart-timeframe">
                    <option value="1m">1分钟</option>
                    <option value="5m">5分钟</option>
                    <option value="30m">30分钟</option>
                    <option value="1H" selected>1小时</option>
                    <option value="2H">2小时</option>
                    <option value="1D">1天</option>
                    <option value="1w">1周</option>
                </select>
                <button onclick="updateChart()">更新图表</button>
                <button onclick="toggleChartType()">切换图表类型</button>
            </div>
            <div class="chart-container">
                <canvas id="trading-chart"></canvas>
            </div>
        </div>
    </div>
    
    <button class="refresh-btn" onclick="refreshData()">🔄 刷新</button>
    
    <!-- Chart.js CDN -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
    
    <script>
        let tradingChart = null;
        let chartType = 'line'; // 'line' or 'candlestick'
        
        // 初始化图表
        function initChart() {
            const ctx = document.getElementById('trading-chart').getContext('2d');
            tradingChart = new Chart(ctx, {
                type: 'line',
                data: {
                    datasets: [{
                        label: '价格',
                        data: [],
                        borderColor: '#4facfe',
                        backgroundColor: 'rgba(79, 172, 254, 0.1)',
                        tension: 0.1
                    }, {
                        label: '买入点',
                        data: [],
                        backgroundColor: '#48bb78',
                        borderColor: '#48bb78',
                        pointRadius: 6,
                        pointHoverRadius: 8,
                        showLine: false,
                        type: 'scatter'
                    }, {
                        label: '卖出点',
                        data: [],
                        backgroundColor: '#e53e3e',
                        borderColor: '#e53e3e',
                        pointRadius: 6,
                        pointHoverRadius: 8,
                        showLine: false,
                        type: 'scatter'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    scales: {
                        x: {
                            type: 'time',
                            time: {
                                displayFormats: {
                                    minute: 'yyyy-MM-dd HH:mm:ss',
                                    hour: 'yyyy-MM-dd HH:mm:ss',
                                    day: 'yyyy-MM-dd HH:mm:ss'
                                }
                            }
                        },
                        y: {
                            beginAtZero: false,
                            title: {
                                display: true,
                                text: '价格 (USDT)'
                            }
                        }
                    },
                    plugins: {
                        legend: {
                            display: true,
                            position: 'top'
                        },
                        tooltip: {
                            mode: 'index',
                            intersect: false,
                            callbacks: {
                                title: function(context) {
                                    // 显示完整的时间格式
                                    if (context[0] && context[0].parsed && context[0].parsed.x) {
                                        const date = new Date(context[0].parsed.x);
                                        return date.getFullYear() + '-' + 
                                               String(date.getMonth() + 1).padStart(2, '0') + '-' + 
                                               String(date.getDate()).padStart(2, '0') + ' ' + 
                                               String(date.getHours()).padStart(2, '0') + ':' + 
                                               String(date.getMinutes()).padStart(2, '0') + ':' + 
                                               String(date.getSeconds()).padStart(2, '0');
                                    }
                                    return '';
                                },
                                label: function(context) {
                                    // 显示价格信息
                                    return context.dataset.label + ': ' + context.parsed.y.toFixed(2);
                                }
                            }
                        }
                    },
                    interaction: {
                        mode: 'nearest',
                        axis: 'x',
                        intersect: false
                    }
                }
            });
        }
        
        // 更新图表
        async function updateChart() {
            const symbol = document.getElementById('chart-symbol').value;
            const timeframe = document.getElementById('chart-timeframe').value;
            
            try {
                // 获取价格数据
                const priceResponse = await fetch(`/api/price_data?symbol=${symbol}&timeframe=${timeframe}`);
                const priceData = await priceResponse.json();
                
                // 获取交易数据
                const tradingResponse = await fetch('/api/trading_chart');
                const tradingData = await tradingResponse.json();
                
                // 更新图表数据
                tradingChart.data.datasets[0].data = priceData.prices || [];
                tradingChart.data.datasets[1].data = tradingData.buy_points || [];
                tradingChart.data.datasets[2].data = tradingData.sell_points || [];
                
                tradingChart.update();
            } catch (error) {
                console.error('更新图表失败:', error);
            }
        }
        
        // 切换图表类型
        function toggleChartType() {
            chartType = chartType === 'line' ? 'candlestick' : 'line';
            // 这里可以实现K线图切换逻辑
            updateChart();
        }
        // 数据刷新函数
        async function refreshData() {
            try {
                // 获取系统状态
                const statusResponse = await fetch('/api/status');
                const statusData = await statusResponse.json();
                updateSystemStatus(statusData);
                
                // 获取策略状态
                const strategiesResponse = await fetch('/api/strategies');
                const strategiesData = await strategiesResponse.json();
                updateStrategies(strategiesData);
                
                // 获取订单
                const ordersResponse = await fetch('/api/orders');
                const ordersData = await ordersResponse.json();
                updateOrders(ordersData);
                
                // 获取持仓
                const positionsResponse = await fetch('/api/positions');
                const positionsData = await positionsResponse.json();
                updatePositions(positionsData);
                
                // 获取盈亏
                const pnlResponse = await fetch('/api/pnl');
                const pnlData = await pnlResponse.json();
                updatePnL(pnlData);
                
            } catch (error) {
                console.error('刷新数据失败:', error);
            }
        }
        
        function updateSystemStatus(data) {
            const container = document.getElementById('system-status');
            container.innerHTML = `
                <div class="metric">
                    <span class="metric-label">运行状态</span>
                    <span class="metric-value">${data.status || '运行中'}</span>
                </div>
                <div class="metric">
                    <span class="metric-label">总交易次数</span>
                    <span class="metric-value">${data.total_trades || 0}</span>
                </div>
                <div class="metric">
                    <span class="metric-label">总盈亏</span>
                    <span class="metric-value ${data.total_pnl >= 0 ? 'positive' : 'negative'}">${(data.total_pnl || 0).toFixed(2)} USDT</span>
                </div>
                <div class="metric">
                    <span class="metric-label">运行时间</span>
                    <span class="metric-value">${formatUptime(data.uptime)}</span>
                </div>
            `;
        }
        
        function updateStrategies(data) {
            const container = document.getElementById('strategies');
            if (!data || data.length === 0) {
                container.innerHTML = '<div class="loading">暂无策略</div>';
                return;
            }
            
            container.innerHTML = data.map(strategy => `
                <div class="strategy-item">
                    <div class="strategy-name">${strategy.name || '未命名策略'}</div>
                    <div class="strategy-details">
                        交易对: ${strategy.symbol || 'N/A'} | 
                        状态: ${strategy.enabled ? '运行中' : '已停止'} | 
                        类型: ${strategy.type || 'N/A'}
                    </div>
                </div>
            `).join('');
        }
        
        function updateOrders(data) {
            const container = document.getElementById('orders');
            if (!data || data.length === 0) {
                container.innerHTML = '<div class="loading">暂无活跃订单</div>';
                return;
            }
            
            container.innerHTML = data.slice(0, 5).map(order => `
                <div class="order-item">
                    <div class="order-header">
                        <span>${order.symbol || 'N/A'}</span>
                        <span class="${order.side === 'buy' ? 'positive' : 'negative'}">${order.side || 'N/A'}</span>
                    </div>
                    <div class="order-details">
                        价格: ${(order.price || 0).toFixed(4)} | 
                        数量: ${(order.amount || 0).toFixed(6)} | 
                        状态: ${order.status || 'N/A'}
                    </div>
                </div>
            `).join('');
        }
        
        function updatePositions(data) {
            const container = document.getElementById('positions');
            if (!data || data.length === 0) {
                container.innerHTML = '<div class="loading">暂无持仓</div>';
                return;
            }
            
            container.innerHTML = data.map(position => `
                <div class="metric">
                    <span class="metric-label">${position.symbol || 'N/A'}</span>
                    <span class="metric-value ${position.pnl >= 0 ? 'positive' : 'negative'}">
                        ${(position.amount || 0).toFixed(6)} (${(position.pnl || 0).toFixed(2)} USDT)
                    </span>
                </div>
            `).join('');
        }
        
        function updatePnL(data) {
            const container = document.getElementById('pnl');
            if (!data || data.length === 0) {
                container.innerHTML = '<div class="loading">暂无盈亏数据</div>';
                return;
            }
            
            const totalPnL = data.reduce((sum, item) => sum + (item.pnl || 0), 0);
            const todayPnL = data.filter(item => {
                const today = new Date().toDateString();
                const itemDate = new Date(item.timestamp).toDateString();
                return today === itemDate;
            }).reduce((sum, item) => sum + (item.pnl || 0), 0);
            
            container.innerHTML = `
                <div class="metric">
                    <span class="metric-label">今日盈亏</span>
                    <span class="metric-value ${todayPnL >= 0 ? 'positive' : 'negative'}">${todayPnL.toFixed(2)} USDT</span>
                </div>
                <div class="metric">
                    <span class="metric-label">累计盈亏</span>
                    <span class="metric-value ${totalPnL >= 0 ? 'positive' : 'negative'}">${totalPnL.toFixed(2)} USDT</span>
                </div>
                <div class="metric">
                    <span class="metric-label">交易记录</span>
                    <span class="metric-value">${data.length} 笔</span>
                </div>
            `;
        }
        
        function formatUptime(uptime) {
            if (!uptime) return 'N/A';
            const start = new Date(uptime);
            const now = new Date();
            const diff = Math.floor((now - start) / 1000);
            
            const hours = Math.floor(diff / 3600);
            const minutes = Math.floor((diff % 3600) / 60);
            const seconds = diff % 60;
            
            return `${hours}h ${minutes}m ${seconds}s`;
        }
        
        function exportData() {
            alert('数据导出功能开发中...');
        }
        
        function showLogs() {
            alert('日志查看功能开发中...');
        }
        
        // 自动刷新
        setInterval(refreshData, 30000); // 每30秒刷新一次
        
        // 页面加载时刷新数据和初始化图表
        document.addEventListener('DOMContentLoaded', function() {
            refreshData();
            initChart();
            updateChart();
        });
    </script>
</body>
</html>
        '''
        return html_template
        
    def _get_trading_chart_data(self):
        """获取交易图表数据"""
        # 尝试从真实交易数据获取
        try:
            # 从真实交易历史中获取买卖点
            buy_points = []
            sell_points = []
            
            # 如果有真实交易数据，从这里获取
            if hasattr(self, 'trading_data') and 'trade_history' in self.trading_data:
                for trade in self.trading_data['trade_history']:
                    point = {
                        'x': trade.get('timestamp', datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
                        'y': trade.get('price', 0)
                    }
                    if trade.get('side') == 'buy':
                        buy_points.append(point)
                    elif trade.get('side') == 'sell':
                        sell_points.append(point)
            
            # 如果没有真实交易数据，从回测结果中获取
            if not buy_points and not sell_points:
                try:
                    # 尝试读取最新的回测结果
                    import os
                    import glob
                    
                    results_dir = os.path.join(os.path.dirname(__file__), '..', 'real_backtest_results')
                    if os.path.exists(results_dir):
                        # 获取最新的JSON数据文件
                        json_files = glob.glob(os.path.join(results_dir, 'real_backtest_data_*.json'))
                        if json_files:
                            latest_file = max(json_files, key=os.path.getctime)
                            
                            with open(latest_file, 'r', encoding='utf-8') as f:
                                backtest_data = json.load(f)
                            
                            # 从回测数据中提取交易点
                            if 'trades' in backtest_data:
                                for trade in backtest_data['trades']:
                                     point = {
                                         'x': trade.get('timestamp', datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
                                         'y': float(trade.get('price', 0))
                                     }
                                     if trade.get('side') == 'buy':
                                         buy_points.append(point)
                                     elif trade.get('side') == 'sell':
                                         sell_points.append(point)
                            
                            self.logger.info(f"从回测结果获取交易点: 买入{len(buy_points)}个, 卖出{len(sell_points)}个")
                
                except Exception as e:
                    self.logger.warning(f"读取回测结果失败: {e}")
            
            # 如果仍然没有数据，返回空数据而不是虚假数据
            if not buy_points and not sell_points:
                self.logger.info("没有找到真实交易数据，返回空的交易图表")
                return {
                    'buy_points': [],
                    'sell_points': []
                }
            
            return {
                'buy_points': buy_points,
                'sell_points': sell_points
            }
            
        except Exception as e:
            self.logger.error(f"获取交易图表数据失败: {e}")
            return {
                'buy_points': [],
                'sell_points': []
            }
    
    def _get_price_data(self, symbol='BTC-USDT', timeframe='1H'):
        """获取真实价格数据"""
        try:
            # 从OKX获取真实K线数据
            from xcquant.exchanges.okx_exchange import OKXExchange
            
            # 使用生产环境配置获取真实数据（不需要API密钥获取公开市场数据）
            config = {
                'api_key': '',
                'secret_key': '',
                'passphrase': '',
                'sandbox': False  # 使用生产环境获取真实数据
            }
            
            exchange = OKXExchange(config)
            
            # 时间周期映射
            period_map = {
                '1m': '1m',
                '5m': '5m', 
                '15m': '15m',
                '30m': '30m',
                '1H': '1H',
                '2H': '2H',
                '4H': '4H',
                '1D': '1D',
                '1w': '1W'
            }
            
            okx_period = period_map.get(timeframe, '1H')
            
            # 获取K线数据
            klines = exchange.get_kline(symbol, okx_period, limit=100)
            
            if klines:
                # 转换为图表需要的格式
                price_data = []
                for kline in klines:
                    timestamp = datetime.fromtimestamp(kline['timestamp'] / 1000)
                    price_data.append({
                        'x': timestamp.strftime('%Y-%m-%d %H:%M:%S'),
                        'y': float(kline['close']),
                        'open': float(kline['open']),
                        'high': float(kline['high']),
                        'low': float(kline['low']),
                        'volume': float(kline['volume'])
                    })
                
                # 按时间排序
                price_data.sort(key=lambda x: x['x'])
                
                self.logger.info(f"成功获取 {symbol} 真实K线数据: {len(price_data)} 条")
                return {'prices': price_data}
            
            # 如果K线数据为空，尝试获取最新价格
            latest_price = exchange.get_latest_price(symbol)
            if latest_price > 0:
                now = datetime.now()
                self.logger.info(f"获取 {symbol} 最新价格: {latest_price}")
                return {'prices': [{
                    'x': now.strftime('%Y-%m-%d %H:%M:%S'),
                    'y': float(latest_price),
                    'open': float(latest_price),
                    'high': float(latest_price),
                    'low': float(latest_price),
                    'volume': 0
                }]}
            
            # 如果都失败了，记录错误并返回空数据
            self.logger.error(f"无法获取 {symbol} 的真实价格数据")
            return {'prices': []}
            
        except Exception as e:
            self.logger.error(f"获取真实价格数据失败: {e}")
            # 发生异常时也不返回虚假数据，而是返回空数据
            return {'prices': []}
    
    def _generate_mock_price_data(self, symbol='BTC-USDT', timeframe='1H'):
        """生成模拟价格数据"""
        import random
        
        now = datetime.now()
        prices = []
        base_price = 45000 if 'BTC' in symbol else 3000 if 'ETH' in symbol else 100
        
        # 根据时间框架确定数据点数量和时间间隔
        timeframe_config = {
            '1m': {'count': 100, 'delta': timedelta(minutes=1)},
            '5m': {'count': 100, 'delta': timedelta(minutes=5)},
            '30m': {'count': 100, 'delta': timedelta(minutes=30)},
            '1H': {'count': 100, 'delta': timedelta(hours=1)},
            '2H': {'count': 100, 'delta': timedelta(hours=2)},
            '1D': {'count': 100, 'delta': timedelta(days=1)},
            '1w': {'count': 52, 'delta': timedelta(weeks=1)}
        }
        
        config = timeframe_config.get(timeframe, timeframe_config['1H'])
        
        for i in range(config['count']):
            timestamp = (now - config['delta'] * (config['count'] - i)).strftime('%Y-%m-%d %H:%M:%S')
            # 生成随机价格波动
            price_change = random.uniform(-0.02, 0.02)  # ±2%的波动
            price = base_price * (1 + price_change + 0.001 * i)  # 轻微上升趋势
            
            prices.append({
                'x': timestamp,
                'y': round(price, 2)
            })
        
        return {'prices': prices}
        
    def update_trading_data(self, data: dict):
        """更新交易数据"""
        self.trading_data.update(data)
        
    def run(self, host='127.0.0.1', port=5001, debug=True):
        """运行Web服务器"""
        self.logger.info(f"启动Web监控面板: http://{host}:{port}")
        self.app.run(host=host, port=port, debug=debug)
        
    async def run_async(self, host='127.0.0.1', port=5001):
        """异步运行Web服务器"""
        import threading
        
        def run_server():
            self.app.run(host=host, port=port, debug=False, use_reloader=False)
            
        server_thread = threading.Thread(target=run_server)
        server_thread.daemon = True
        server_thread.start()
        
        self.logger.info(f"Web监控面板已启动: http://{host}:{port}")


def main():
    """主函数"""
    config_path = project_root / "config_okx_demo.yaml"
    
    dashboard = WebDashboard(str(config_path))
    
    # 添加一些示例数据
    dashboard.update_trading_data({
        'strategies': [
            {
                'name': 'BTC网格策略',
                'symbol': 'BTC-USDT',
                'type': 'spot',
                'enabled': True
            }
        ],
        'orders': [
            {
                'symbol': 'BTC-USDT',
                'side': 'buy',
                'price': 45000.0,
                'amount': 0.001,
                'status': 'open'
            }
        ],
        'positions': [
            {
                'symbol': 'BTC-USDT',
                'amount': 0.001,
                'pnl': 5.0
            }
        ],
        'pnl_history': [
            {
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'pnl': 5.0,
                'symbol': 'BTC-USDT'
            }
        ]
    })
    
    print("🌐 启动Web监控面板...")
    print("📱 访问地址: http://127.0.0.1:5001")
    print("⏹️  按 Ctrl+C 停止服务")
    
    try:
        dashboard.run()
    except KeyboardInterrupt:
        print("\n👋 Web监控面板已停止")


if __name__ == "__main__":
    main()